package com.matt.service.impl;

import com.fasterxml.jackson.databind.JavaType;
import com.matt.domain.news.SystemNotification;
import com.matt.domain.news.SystemNotificationMenu;
import com.matt.foundation.constant.SystemNotificationConstant;
import com.matt.commons.exception.BusinessException;

import com.matt.foundation.model.ErrorCode;
import com.matt.foundation.query.NewsQuery;
import com.matt.foundation.utils.DateUtil;
import com.matt.foundation.utils.ModelUtil;
import com.matt.foundation.vo.news.NewsVo;
import com.matt.foundation.vo.news.WebNewsVo;
import com.matt.repository.base.SystemNotificationMenuNativeRepository;
import com.matt.repository.base.SystemNotificationNativeRepository;
import com.matt.repository.news.SystemNotificationMenuRepository;
import com.matt.repository.news.SystemNotificationRepository;
import com.matt.service.SystemNotificationService;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service;

import javax.transaction.Transactional;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * *******************************
 * Created by lch.
 * form com.matt
 * on $date$
 * *******************************
 */
@Service
public class SystemNotificationServiceImpl implements SystemNotificationService {

    @Autowired
    private SystemNotificationRepository systemNotificationRepository;

    @Autowired
    private SystemNotificationMenuRepository systemNotificationMenuRepository;

    @Autowired
    private SystemNotificationNativeRepository systemNotificationNativeRepository;

    @Autowired
    private SystemNotificationMenuNativeRepository systemNotificationMenuNativeRepository;

    @Transactional
    @Override
    public SystemNotification add(String name, String date, String text, String json) {
        SystemNotification vo = SystemNotification.of(name, text, "", DateUtil.parseToDate(date));
        if (!"[]".equals(json) && !"null".equals(json) && StringUtils.isNotBlank(json))
            vo.setCategory(SystemNotificationConstant.Category.MENU.codeOf());
        systemNotificationRepository.save(vo);
        if (StringUtils.isNotBlank(vo.getId()) && !"null".equals(json) && StringUtils.isNotBlank(json)) {
            JavaType javaType = ModelUtil.objectMapper.getTypeFactory().constructParametricType(ArrayList.class, SystemNotificationMenu.class);
            try {
                List<SystemNotificationMenu> list = ModelUtil.objectMapper.readValue(json, javaType);
                for (SystemNotificationMenu systemNotificationMenu : list) {
                    systemNotificationMenu.setSystemNotificationId(vo.getId());
                    systemNotificationMenuRepository.save(systemNotificationMenu);
                }
            } catch (IOException e) {
                e.printStackTrace();
                System.out.println("json 转化出错！");
            }
        }
        return vo;
    }

    @Override
    public Page<SystemNotification> page(NewsQuery query) {
        List<SystemNotification> list = systemNotificationNativeRepository.findByQuery(query);
        Long count = systemNotificationNativeRepository.findCountByQuery(query);
        return new PageImpl<SystemNotification>(list, PageRequest.of(query.getPageNum(), query.getPageSize()), count);
    }

    @Transactional
    @Override
    public SystemNotification update(String id, String name, String date, String text, String json) {
        SystemNotification vo = systemNotificationRepository.getOne(id);
        if (!"[]".equals(json) && !"null".equals(json) && StringUtils.isNotBlank(json))
            vo.setCategory(SystemNotificationConstant.Category.MENU.codeOf());
        else
            vo.setCategory(SystemNotificationConstant.Category.NON_MENU.codeOf());
        vo.setDate(DateUtil.parseToDate(date));
        vo.setName(name);
        vo.setText(text);
        systemNotificationRepository.save(vo);
        if (StringUtils.isNotBlank(vo.getId()) && !"null".equals(json) && StringUtils.isNotBlank(json)) {
            JavaType javaType = ModelUtil.objectMapper.getTypeFactory().constructParametricType(ArrayList.class, SystemNotificationMenu.class);
            try {
                List<SystemNotificationMenu> list = ModelUtil.objectMapper.readValue(json, javaType);
                //删除老数据
                int count = systemNotificationMenuRepository.deleteBySystemNotificationId(vo.getId());
                for (SystemNotificationMenu news : list) {
                    SystemNotificationMenu record = null;
                    if (StringUtils.isNotBlank(news.getId()))
                        record = systemNotificationMenuRepository.getOne(news.getId());
                    else
                        record = new SystemNotificationMenu();
                    record.setSystemNotificationId(vo.getId());
                    record.setContent(news.getContent());
                    record.setMenuId(news.getMenuId());
                    record.setMenuName(news.getMenuName());
                    record.setIsEdit(news.getIsEdit());
                    systemNotificationMenuRepository.save(record);
                }
            } catch (IOException e) {
                e.printStackTrace();
                System.out.println("json 转化出错！");
            }
        }
        return vo;
    }

    @Override
    public NewsVo detail(String id) {
        SystemNotification systemNotification = systemNotificationRepository.getOne(id);
        List<SystemNotificationMenu> systemNotificationMenuList = systemNotificationMenuRepository.findBySystemNotificationId(id);
        return NewsVo.of(systemNotification, systemNotificationMenuList);
    }

    @Transactional
    @Override
    public boolean delete(String id) {
        try {
            //先删除子表
            systemNotificationMenuRepository.deleteBySystemNotificationId(id);
            //在删除主表
            systemNotificationRepository.deleteById(id);
        } catch (Exception e1) {
            throw new BusinessException(ErrorCode.DELETE_ERROR, "删除通告失败！");
        }
        return true;
    }

    @Override
    public WebNewsVo recentlyNews() {
        //查询首页首页消息
        SystemNotification systemNotification = systemNotificationNativeRepository.findTopNews();
        //查询菜单消息
        List<SystemNotificationMenu> list = systemNotificationMenuNativeRepository.getNewsInfo();
        return WebNewsVo.of(systemNotification, list);
    }
}
